package drds.global_transaction.global_transaction_manager.api;

import drds.global_transaction.api.exception.GlobalTransactionException;

public class GlobalTransactionTemplate
{

	public Object execute(GlobalTransactionExecutor globalTransactionExecutor) throws GlobalTransactionExecutionException
	{

		// 1. get or create a global transaction
		GlobalTransaction globalTransaction = GlobalTransactionContext.getCurrentOrCreateGlobalTransaction();
		// 2. global transaction begin
		try
		{
			globalTransaction.begin(globalTransactionExecutor.timeout(), globalTransactionExecutor.name());
		} catch (GlobalTransactionException txe)
		{
			throw new GlobalTransactionExecutionException(globalTransaction, txe, GlobalTransactionExecutionExceptionCode.begin_global_transaction_failure);

		}
		Object resultObject = null;
		try
		{
			// here is your business
			resultObject = globalTransactionExecutor.execute();
		} catch (Throwable ex)
		{
			// 3. any business exception, globalTransactionRollback.
			try
			{
				globalTransaction.rollback();
				// 3.1 Successfully rolled back
				throw new GlobalTransactionExecutionException(globalTransaction, GlobalTransactionExecutionExceptionCode.rollback_global_transaction_done, ex);
			} catch (GlobalTransactionException txe)
			{
				// 3.2 failed to globalTransactionRollback
				throw new GlobalTransactionExecutionException(globalTransaction, txe, GlobalTransactionExecutionExceptionCode.rollback_global_transaction_failure, ex);
			}

		}
		// 4. everything is fine, globalTransactionCommit.
		try
		{
			globalTransaction.commit();
		} catch (GlobalTransactionException txe)
		{
			// 4.1 failed to globalTransactionCommit
			throw new GlobalTransactionExecutionException(globalTransaction, txe, GlobalTransactionExecutionExceptionCode.commit_global_transaction_failure);
		}
		return resultObject;
	}

}
